<?php
declare (strict_types = 1);

namespace app\api\model;

use think\Model;

/**
 * Menu 模型
 * 对应数据表：sys_menu
 */
class Menu extends Model
{
    // 设置数据表名（不含前缀）
    protected $name = 'sys_menu_new';
    
    // 设置主键
    protected $pk = 'id';
    
    // 自动时间戳
    protected $autoWriteTimestamp = true;
    
    // 定义时间戳字段名
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    
    // 字段类型转换
    protected $type = [
        'id'                => 'integer',
        'parent_id'         => 'integer',
        'menu_type'         => 'string',  // 前端期望字符串类型 '1' 或 '2'
        'icon_type'         => 'string',  // 前端期望字符串类型 '1' 或 '2'
        'status'            => 'string',  // 前端期望字符串类型 '1' 或 '2'
        'keep_alive'        => 'boolean',
        'constant'          => 'boolean',
        'order'             => 'integer',
        'hide_in_menu'      => 'boolean',
        'multi_tab'         => 'boolean',
        'fixed_index_in_tab' => 'integer',
        'create_time'       => 'datetime',
        'update_time'       => 'datetime',
    ];
    
    // JSON字段
    protected $json = ['query_params', 'buttons'];
    
    // JSON数据转换为数组
    protected $jsonAssoc = true;
    
    /**
     * 获取器：query字段（前端使用query而非query_params）
     * @param $value
     * @return array
     */
    public function getQueryAttr($value, $data)
    {
        if (isset($data['query_params'])) {
            $query = json_decode($data['query_params'], true);
            return $query ?: [];
        }
        return [];
    }
    
    /**
     * 修改器：query字段保存为query_params
     * @param $value
     * @return string
     */
    public function setQueryAttr($value)
    {
        if (is_array($value)) {
            return json_encode($value, JSON_UNESCALE_UNICODE);
        }
        return $value;
    }
    
    /**
     * 获取器：buttons字段转换
     * @param $value
     * @return array
     */
    public function getButtonsAttr($value, $data)
    {
        if (isset($data['buttons']) && !empty($data['buttons'])) {
            if (is_string($data['buttons'])) {
                $buttons = json_decode($data['buttons'], true);
                return $buttons ?: [];
            }
            return $data['buttons'];
        }
        return [];
    }
    
    /**
     * 修改器：buttons字段
     * @param $value
     * @return string
     */
    public function setButtonsAttr($value)
    {
        if (is_array($value)) {
            return json_encode($value, JSON_UNESCALE_UNICODE);
        }
        return $value;
    }
    
    /**
     * 获取菜单树形结构
     * @param int $parentId 父菜单ID
     * @param array $menus 所有菜单数据
     * @return array
     */
    public static function buildMenuTree(int $parentId = 0, array $menus = []): array
    {
        if (empty($menus)) {
            $menus = self::order('order', 'asc')
                ->order('id', 'asc')
                ->select()
                ->toArray();
        }
        
        $tree = [];
        foreach ($menus as $menu) {
            if ($menu['parent_id'] == $parentId) {
                $children = self::buildMenuTree($menu['id'], $menus);
                if (!empty($children)) {
                    $menu['children'] = $children;
                } else {
                    $menu['children'] = null;  // 前端可能需要null而不是空数组
                }
                $tree[] = $menu;
            }
        }
        
        return $tree;
    }
    
    /**
     * 获取简化的菜单树（用于下拉选择）
     * @return array
     */
    public static function getMenuTreeForSelect(): array
    {
        $menus = self::where('status', '1')
            ->order('order', 'asc')
            ->order('id', 'asc')
            ->select()
            ->toArray();
        
        return self::buildSimpleTree(0, $menus);
    }
    
    /**
     * 构建简化树形结构
     * @param int $parentId
     * @param array $menus
     * @return array
     */
    private static function buildSimpleTree(int $parentId, array $menus): array
    {
        $tree = [];
        foreach ($menus as $menu) {
            if ($menu['parent_id'] == $parentId) {
                $node = [
                    'id'    => $menu['id'],
                    'label' => $menu['menu_name'],
                    'pId'   => $menu['parent_id'],
                ];
                
                $children = self::buildSimpleTree($menu['id'], $menus);
                if (!empty($children)) {
                    $node['children'] = $children;
                }
                
                $tree[] = $node;
            }
        }
        
        return $tree;
    }
    
    /**
     * 获取菜单及其所有子菜单ID
     * @param int $menuId
     * @return array
     */
    public static function getMenuAndChildrenIds(int $menuId): array
    {
        $ids = [$menuId];
        $children = self::where('parent_id', $menuId)->column('id');
        
        if (!empty($children)) {
            foreach ($children as $childId) {
                $ids = array_merge($ids, self::getMenuAndChildrenIds($childId));
            }
        }
        
        return $ids;
    }
    
    /**
     * 检查菜单名称是否已存在
     * @param string $menuName
     * @param int $excludeId 排除的ID（编辑时使用）
     * @return bool
     */
    public static function isMenuNameExists(string $menuName, int $excludeId = 0): bool
    {
        $query = self::where('menu_name', $menuName);
        
        if ($excludeId > 0) {
            $query->where('id', '<>', $excludeId);
        }
        
        return $query->count() > 0;
    }
    
    /**
     * 检查路由名称是否已存在
     * @param string $routeName
     * @param int $excludeId 排除的ID（编辑时使用）
     * @return bool
     */
    public static function isRouteNameExists(string $routeName, int $excludeId = 0): bool
    {
        $query = self::where('route_name', $routeName);
        
        if ($excludeId > 0) {
            $query->where('id', '<>', $excludeId);
        }
        
        return $query->count() > 0;
    }
}
